//
//  TrtcCmd.swift
//  onemeetingmac
//
//  Created by 张衡 on 2020/3/25.
//  Copyright © 2020 onemeeting. All rights reserved.
//

import Foundation
import TXLiteAVSDK_TRTC_Mac

struct TkStatistics {
    var width:CGFloat                         = 0
    var height:CGFloat                        = 0
    var streamType: TRTCVideoStreamType       = .small
    //userId==nil 本地，否则远程
    var userId:String?
}


class TrtcCmd: NSObject {
    static let shared = TrtcCmd()
}

extension TrtcCmd:TRTCAudioFrameDelegate {
    func onCapturedAudioFrame(_ frame: TRTCAudioFrame) { }
}

extension TrtcCmd:TRTCCloudDelegate {
    func onExitRoom(_ reason: Int) {
        if let roomid = Td.sh().params.roomId {
            let isLeave = Td.sh().cloud.isLeave
            if String.isHostId() && isLeave == false  {
                IMcmd.shared.exit(userId: nil, groupId: nil) {
                   IMEngine.shared.dismissGroup(groupId: roomid, succ: {
                        NetEngine.requstCloseRoom(roomId: roomid, success: nil)
                   }, fail: nil)
                }
            }
        }
        
        if  Td.sh().scene == .live {
            IMcmd.shared.audience(isEnter: false)
        }
        
        defer {
            Td.destory()
            TXLiteManager.destroy()
            IMEngine.shared.unInit()
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+0.1, execute: {
                TCGirdRender.destory()
            })
        }
        TrtcEngine.exit()
    }
    
    func onEnterRoom(_ result: Int) {
        TXLiteManager.isEntered = true
    }
    
    func onError(_ errCode: TXLiteAVError, errMsg: String?, extInfo: [AnyHashable : Any]?) {
        GToast.show(msg: errMsg!)
    }
    
    func onUserVoiceVolume(_ userVolumes: [TRTCVolumeInfo], totalVolume: Int) {
        let localInfos = userVolumes.filter { (info) -> Bool in
           return info.userId == nil
        }
        //本地声音
        if localInfos.count > 0 {
            let volume = CGFloat(localInfos[0].volume)
            NotificationCenter.default.post(name: MTCapAudioNotification, object: volume)
        }
    }
    
    func onUserAudioAvailable(_ userId: String, available: Bool) {
        MTNot.postNotMute(userid: userId, isok: !available)
    }
    
    func onUserVideoAvailable(_ userId: String, available: Bool) {
        MTNot.postNotVdOpen(isok: available, userid: userId)
    }
    
    func to(streamType:ReStreamType) -> TRTCVideoStreamType {
        switch streamType {
        case .sub:
            return TRTCVideoStreamType.sub
        case .small:
            return TRTCVideoStreamType.small
        case .big:
            return TRTCVideoStreamType.big
        }
    }
    func onStatistics(_ statistics: TRTCStatistics) {
        var all:[TkStatistics] = []     //全部的视频流
        var tks:[TkStatistics] = []     //显示的视频流
        
        if let locals = statistics.localStatistics {
            let list =  locals.map { (local) -> TkStatistics in
                var tk = TkStatistics()
                tk.width = CGFloat(local.width)
                tk.height = CGFloat(local.height)
                tk.streamType = local.streamType
                return tk
            }
            all.append(contentsOf: list)
        }
        if let remotes = statistics.remoteStatistics {
            let list =  remotes.map { (remot) -> TkStatistics in
                var tkRemot = TkStatistics()
                tkRemot.userId = remot.userId
                tkRemot.width = CGFloat(remot.width)
                tkRemot.height = CGFloat(remot.height)
                tkRemot.streamType = remot.streamType
                return tkRemot
            }
            all.append(contentsOf: list)
        }
        
        ////////////
        let hasSub = all.contains(where: {$0.streamType == .sub})
        if hasSub == false{
            //会议状态
            let infoList = TCGirdRender.shared().renderer.infoList
            infoList.forEach { (value) in
                let stream = all.first(where: { (tk) -> Bool in
                    if let userid = Td.sh().lc.userId {
                        let userid1 = tk.userId ?? userid
                        return userid1 == value.userId
                    }
                    return false
                })
                if let tk = stream {
                    tks.append(tk)
                }
            }
        }else {
            //共享状态
            let infoList = TCGirdRender.shared().renderer.subInfoList
            infoList.forEach { (value) in
                if value.streamType == .sub {
                    if let subStream = all.first(where: {$0.streamType == self.to(streamType: value.streamType)}) {
                        tks.append(subStream)
                    }
                }else {
                    if let userid = Td.sh().lc.userId {
                        let userid = value.userId == userid ? nil:value.userId
                        if let stram = all.first(where: {$0.userId == userid}) {
                            tks.append(stram)
                        }
                    }
                }
            }
        }

        //单视频放大
        if let specifyUid = TCGirdRender.shared().renderer.specifyUid {
            let isfirst = tks.first { (info) -> Bool in
                let userid = info.userId ?? Td.sh().lc.userId!
                return specifyUid == userid
            }
            if let first = isfirst {
                tks.removeAll()
                tks.append(first)
            }
        }
        
        TXLiteManager.shared().ksta = tks
        TXLiteManager.needPushMix()
    }
    
    func onFirstVideoFrame(_ userId: String, streamType: TRTCVideoStreamType, width: Int32, height: Int32) {
        //print("ssssss =\(userId),\(streamType),\(width),\(height)")
    }
    
    func onUserSubStreamAvailable(_ userId: String, available: Bool) {
        Td.sh().sd.isSding = available
        Td.sh().sd.sdUserId = userId
        NotificationCenter.default.post(name: MTSubStreamNotification, object: StreamMode.init(userId: userId, available: available))
    }
    
    func checkAdc(userId:String) -> AdcInfo?{
        if Td.sh().scene == .live {
            let adcs = Td.sh().usr.adcs
            let fi = adcs.first { (info) -> Bool in
                return info.userId==userId
            }
            if let adcInfo = fi {
                MTNot.postDeleteAdc(userId: adcInfo.userId)
                return adcInfo
            }
        }
        return nil
    }
    
    func onRemoteUserEnterRoom(_ userId: String) {
        let adcInfo = self.checkAdc(userId: userId)
        IMcmd.shared.modifyName(name: Td.sh().lc.nickName)
        MTNot.postAddUser(userId: userId,name: adcInfo?.nickName)
        
        if String.isHostId() {
            if Td.sh().cloud.isALLMute == true {
                IMcmd.shared.allMute(isok: true)
            }
            if Td.sh().scene == .meeting {
                if Td.sh().cloud.focusId != mt_none {
                    IMcmd.shared.focusUser(userId: Td.sh().cloud.focusId)
                }
                if Td.sh().usr.remote.count+2 > Td.sh().cloud.meetingCount {
                    IMcmd.shared.kick(userId: userId)
                }
            }
        }
    }
    
    func onRemoteUserLeaveRoom(_ userId: String, reason: Int) {
        MTNot.postDeleteUser(userId: userId)
    }
    
    func onRecvSEIMsg(_ userId: String, message: Data) {
        
    }
    
    func onFirstAudioFrame(_ userId: String) {
        
    }
    
    func onRecvCustomCmdMsgUserId(_ userId: String, cmdID: Int, seq: UInt32, message: Data) {
        
    }
    
    func onScreenCapturePaused(_ reason: Int32) {
        
    }
    func onScreenCaptureStarted() {
        
    }
    
    func onScreenCaptureStoped(_ reason: Int32) {
        
    }
    
    func onScreenCaptureResumed(_ reason: Int32) {
        
    }
    
    func onSwitchRole(_ errCode: TXLiteAVError, errMsg: String?) {
        
    }
    
    
    func onSetMixTranscodingConfig(_ err: Int32, errMsg: String) {
        
    }
    
    func onMicDidReady() {
        
    }
    
    func onCameraDidReady() {
        
    }
    
    
    //服务器连接
    func onConnectionLost() {
        
    }
    
    func onTryToReconnect() {
        
    }
    
    func onConnectionRecovery() {
        
    }
    
    
    
}


